#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "astaralgorithm.h"
#include "bfsalgorithm.h"
#include "dfsalgorithm.h"
#include <QApplication>
#include <QMessageBox>
#include <QInputDialog>
#include <QHeaderView>
#include <QMouseEvent>
#include <QDrag>
#include <QMimeData>
#include <QSet>
#include <QCheckBox>
#include <QDialog>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QPushButton>
#include <memory>
#include <climits>
#include <cfloat>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
    , m_puzzleSize(3)
    , m_isSearching(false)
    , m_isManualInput(false)
    , m_isSettingInitial(true)
    , m_demoTimer(new QTimer(this))
    , m_currentDemoStep(0)
    , m_isDemoRunning(false)
    , m_logStepCounter(0)
{
    ui->setupUi(this);
    setupUI();
    setupConnections();
    
    // 连接演示计时器
    connect(m_demoTimer, &QTimer::timeout, this, &MainWindow::onDemoStep);
    
    // 初始化默认状态
    onDefaultState();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::setupUI()
{
    
    
    // 创建数码网格
    createPuzzleGrid(ui->widget_initialGrid, m_puzzleSize);
    createPuzzleGrid(ui->widget_goalGrid, m_puzzleSize);
    createPuzzleGrid(ui->widget_currentState, m_puzzleSize);
    
    // 设置表格
    ui->tableWidget_results->setAlternatingRowColors(true);
    ui->tableWidget_results->setSelectionBehavior(QAbstractItemView::SelectRows);
    
    // 设置列宽 - 确保所有列都能完整显示
    QHeaderView* header = ui->tableWidget_results->horizontalHeader();
    header->setStretchLastSection(false);  // 禁用最后一列自动拉伸
    
    // 设置各列的固定宽度 - 优化后更紧凑
    ui->tableWidget_results->setColumnWidth(0, 130);  // 算法列
    ui->tableWidget_results->setColumnWidth(1, 70);   // 是否成功列
    ui->tableWidget_results->setColumnWidth(2, 50);   // 步数列
    ui->tableWidget_results->setColumnWidth(3, 85);   // 生成节点数列
    ui->tableWidget_results->setColumnWidth(4, 85);   // 扩展节点数列
    ui->tableWidget_results->setColumnWidth(5, 100);  // 运行时间列
    
    // 设置表格的最小宽度以容纳所有列
    int totalWidth = 130 + 70 + 50 + 85 + 85 + 100 + 20; // 加上边距
    ui->tableWidget_results->setMinimumWidth(totalWidth);
    
    // 设置列的调整模式
    header->setSectionResizeMode(0, QHeaderView::Fixed);
    header->setSectionResizeMode(1, QHeaderView::Fixed);
    header->setSectionResizeMode(2, QHeaderView::Fixed);
    header->setSectionResizeMode(3, QHeaderView::Fixed);
    header->setSectionResizeMode(4, QHeaderView::Fixed);
    header->setSectionResizeMode(5, QHeaderView::Fixed);
    
    // 设置splitter的初始比例 (左侧:右侧 = 47:53)
    ui->splitter->setSizes({540, 620});
    
    // 设置状态栏
    ui->statusbar->showMessage("就绪");
}

void MainWindow::setupConnections()
{
    // 数码大小选择
    connect(ui->comboBox_size, QOverload<int>::of(&QComboBox::currentIndexChanged),
            this, &MainWindow::onSizeChanged);
    
    // 状态生成按钮
    connect(ui->pushButton_default, &QPushButton::clicked, this, &MainWindow::onDefaultState);
    connect(ui->pushButton_random, &QPushButton::clicked, this, &MainWindow::onRandomState);
    connect(ui->pushButton_manual, &QPushButton::clicked, this, &MainWindow::onManualState);
    
    // 搜索控制
    connect(ui->pushButton_runAll, &QPushButton::clicked, this, &MainWindow::onRunAllAlgorithms);
    

    
    // 结果操作
    connect(ui->pushButton_clearResults, &QPushButton::clicked, this, &MainWindow::onClearResults);
    

    
    // 算法独立演示按钮
    connect(ui->pushButton_demo_astar_manhattan, &QPushButton::clicked, this, &MainWindow::onDemoAStarManhattan);
    connect(ui->pushButton_demo_astar_misplaced, &QPushButton::clicked, this, &MainWindow::onDemoAStarMisplaced);
    connect(ui->pushButton_demo_bfs, &QPushButton::clicked, this, &MainWindow::onDemoBFS);
    connect(ui->pushButton_demo_dfs, &QPushButton::clicked, this, &MainWindow::onDemoDFS);
    
    // 连接演示控制按钮
    connect(ui->pushButton_demo_pause, &QPushButton::clicked, this, &MainWindow::onDemoPause);
    connect(ui->pushButton_demo_resume, &QPushButton::clicked, this, &MainWindow::onDemoResume);
    connect(ui->pushButton_demo_stop, &QPushButton::clicked, this, &MainWindow::onDemoStop);
    
    // 连接日志控制按钮
    connect(ui->pushButton_clearLog, &QPushButton::clicked, this, &MainWindow::onClearLog);

}

void MainWindow::createPuzzleGrid(QWidget* parent, int size)
{
    // 清除现有布局
    if (parent->layout()) {
        QLayoutItem* item;
        while ((item = parent->layout()->takeAt(0)) != nullptr) {
            delete item->widget();
            delete item;
        }
        delete parent->layout();
    }
    
    QGridLayout* layout = new QGridLayout(parent);
    layout->setSpacing(4);
    layout->setContentsMargins(6, 6, 6, 6);
    
    // 根据父控件确定按钮容器
    std::vector<std::vector<QPushButton*>>* buttons = nullptr;
    if (parent == ui->widget_initialGrid) {
        m_initialGridLayout = layout;
        m_initialButtons.clear();
        m_initialButtons.resize(size, std::vector<QPushButton*>(size));
        buttons = &m_initialButtons;
    } else if (parent == ui->widget_goalGrid) {
        m_goalGridLayout = layout;
        m_goalButtons.clear();
        m_goalButtons.resize(size, std::vector<QPushButton*>(size));
        buttons = &m_goalButtons;
    } else if (parent == ui->widget_currentState) {
        m_currentGridLayout = layout;
        m_currentButtons.clear();
        m_currentButtons.resize(size, std::vector<QPushButton*>(size));
        buttons = &m_currentButtons;
    }
    
    // 创建按钮
    for (int i = 0; i < size; ++i) {
        for (int j = 0; j < size; ++j) {
            QPushButton* button = new QPushButton();
            // 统一尺寸策略，消除不同数字造成的尺寸差异
            button->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
            button->setMinimumSize(48, 48);  // 设置最小尺寸确保方块不会太小
            button->setMaximumSize(80, 80);  // 设置最大尺寸防止方块过大
            
            // 根据不同区域设置不同的样式颜色
            QString styleSheet;
            if (parent == ui->widget_currentState) {
                // 过程演示区域使用绿色系
                styleSheet = 
                    "QPushButton {"
                    "   border: 2px solid #00aa44;"
                    "   border-radius: 4px;"
                    "   font-size: 16px;"
                    "   font-weight: bold;"
                    "   background-color: #e6ffe6;"
                    "}"
                    "QPushButton:hover {"
                    "   background-color: #ccffcc;"
                    "}"
                    "QPushButton:pressed {"
                    "   background-color: #b3ffb3;"
                    "}";
            } else {
                // 初始状态和目标状态使用蓝色系
                styleSheet = 
                    "QPushButton {"
                    "   border: 2px solid #0066cc;"
                    "   border-radius: 4px;"
                    "   font-size: 16px;"
                    "   font-weight: bold;"
                    "   background-color: #e6f3ff;"
                    "}"
                    "QPushButton:hover {"
                    "   background-color: #cce7ff;"
                    "}"
                    "QPushButton:pressed {"
                    "   background-color: #b3d9ff;"
                    "}";
            }
            button->setStyleSheet(styleSheet);
            
            button->setProperty("row", i);
            button->setProperty("col", j);
            button->setProperty("grid", parent == ui->widget_initialGrid ? "initial" : 
                               parent == ui->widget_goalGrid ? "goal" : "current");
            
            // 只有初始和目标状态的按钮可以点击（用于手动输入）
            if (parent != ui->widget_currentState) {
                connect(button, &QPushButton::clicked, this, &MainWindow::onGridButtonClicked);
            }
            
            layout->addWidget(button, i, j);
            if (buttons) {
                (*buttons)[i][j] = button;
            }
        }
    }

    // 保证各行列等比伸展，方块尽可能相同大小
    for (int r = 0; r < size; ++r) {
        layout->setRowStretch(r, 1);
        layout->setRowMinimumHeight(r, 48);
    }
    for (int c = 0; c < size; ++c) {
        layout->setColumnStretch(c, 1);
        layout->setColumnMinimumWidth(c, 48);
    }
    
    // 设置布局的对齐方式，确保网格居中显示
    layout->setAlignment(Qt::AlignCenter);
    
    // 确保父控件有合适的尺寸策略
    parent->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
}

void MainWindow::updatePuzzleDisplay(QWidget* parent, const PuzzleState& state)
{
    std::vector<std::vector<QPushButton*>>* buttons = nullptr;
    if (parent == ui->widget_initialGrid) {
        buttons = &m_initialButtons;
    } else if (parent == ui->widget_goalGrid) {
        buttons = &m_goalButtons;
    } else if (parent == ui->widget_currentState) {
        buttons = &m_currentButtons;
    }
    
    if (!buttons || buttons->empty()) return;
    
    int size = state.getSize();
    // 检查按钮数组大小是否与状态大小匹配
    if (buttons->size() != static_cast<size_t>(size) || (*buttons)[0].size() != static_cast<size_t>(size)) {
        return; // 大小不匹配，直接返回避免崩溃
    }
    
    for (int i = 0; i < size; ++i) {
        for (int j = 0; j < size; ++j) {
            int value = state.getValue(i, j);
            QPushButton* button = (*buttons)[i][j];
            
            // 根据不同区域设置不同的样式颜色
            QString emptyStyleSheet, numberStyleSheet;
            if (parent == ui->widget_currentState) {
                // 过程演示区域使用绿色系
                emptyStyleSheet = 
                    "QPushButton {"
                    "   border: 2px solid #ccc;"
                    "   border-radius: 4px;"
                    "   font-size: 16px;"
                    "   font-weight: bold;"
                    "   background-color: #f0f0f0;"
                    "}"
                    "QPushButton:hover {"
                    "   background-color: #e0e0e0;"
                    "}"
                    "QPushButton:pressed {"
                    "   background-color: #d0d0d0;"
                    "}";
                numberStyleSheet = 
                    "QPushButton {"
                    "   border: 2px solid #00aa44;"
                    "   border-radius: 4px;"
                    "   font-size: 16px;"
                    "   font-weight: bold;"
                    "   background-color: #e6ffe6;"
                    "}"
                    "QPushButton:hover {"
                    "   background-color: #ccffcc;"
                    "}"
                    "QPushButton:pressed {"
                    "   background-color: #b3ffb3;"
                    "}";
            } else {
                // 初始状态和目标状态使用蓝色系
                emptyStyleSheet = 
                    "QPushButton {"
                    "   border: 2px solid #ccc;"
                    "   border-radius: 4px;"
                    "   font-size: 16px;"
                    "   font-weight: bold;"
                    "   background-color: #f0f0f0;"
                    "}"
                    "QPushButton:hover {"
                    "   background-color: #e0e0e0;"
                    "}"
                    "QPushButton:pressed {"
                    "   background-color: #d0d0d0;"
                    "}";
                numberStyleSheet = 
                    "QPushButton {"
                    "   border: 2px solid #0066cc;"
                    "   border-radius: 4px;"
                    "   font-size: 16px;"
                    "   font-weight: bold;"
                    "   background-color: #e6f3ff;"
                    "}"
                    "QPushButton:hover {"
                    "   background-color: #cce7ff;"
                    "}"
                    "QPushButton:pressed {"
                    "   background-color: #b3d9ff;"
                    "}";
            }
            
            if (value == 0) {
                button->setText("");
                button->setStyleSheet(emptyStyleSheet);
            } else {
                button->setText(QString::number(value));
                button->setStyleSheet(numberStyleSheet);
            }
        }
    }
}


void MainWindow::onSizeChanged()
{
    int index = ui->comboBox_size->currentIndex();
    m_puzzleSize = (index == 0) ? 3 : 4;
    
    // 停止当前搜索（如果正在进行）
    if (m_isSearching) {
        m_isSearching = false;
        m_algorithm.reset();
        enableControls(true);
    }
    
    // 重新创建网格
    createPuzzleGrid(ui->widget_initialGrid, m_puzzleSize);
    createPuzzleGrid(ui->widget_goalGrid, m_puzzleSize);
    createPuzzleGrid(ui->widget_currentState, m_puzzleSize);
    
    // 设置默认状态
    onDefaultState();
}

void MainWindow::onDefaultState()
{
    if (m_puzzleSize == 3) {
        m_initialState = PuzzleState::getDefaultInitialState();
        m_goalState = PuzzleState::getDefaultGoalState();
    } else {
        // 15数码的默认状态
        std::vector<std::vector<int>> initial = {
            {1, 2, 3, 4},
            {5, 6, 7, 8},
            {9, 10, 11, 12},
            {13, 15, 14, 0}
        };
        std::vector<std::vector<int>> goal = {
            {1, 2, 3, 4},
            {5, 6, 7, 8},
            {9, 10, 11, 12},
            {13, 14, 15, 0}
        };
        m_initialState = PuzzleState(initial);
        m_goalState = PuzzleState(goal);
    }
    
    updatePuzzleDisplay(ui->widget_initialGrid, m_initialState);
    updatePuzzleDisplay(ui->widget_goalGrid, m_goalState);
    updatePuzzleDisplay(ui->widget_currentState, m_initialState);
    m_currentState = m_initialState;
    
    ui->statusbar->showMessage("已设置默认状态");
}

void MainWindow::onRandomState()
{
    // 随机生成初始状态
    m_initialState = PuzzleState::generateRandomSolvableState(m_puzzleSize);
    
    // 随机生成目标状态
    m_goalState = PuzzleState::generateRandomSolvableState(m_puzzleSize);
    
    // 确保初始状态和目标状态不相同
    while (m_initialState == m_goalState) {
        m_goalState = PuzzleState::generateRandomSolvableState(m_puzzleSize);
    }
    
    // 验证从初始状态到目标状态是可解的
    if (!m_initialState.isSolvable(m_goalState)) {
        // 如果不可解，重新生成目标状态
        m_goalState = PuzzleState::generateRandomSolvableState(m_puzzleSize);
        while (m_initialState == m_goalState || !m_initialState.isSolvable(m_goalState)) {
            m_goalState = PuzzleState::generateRandomSolvableState(m_puzzleSize);
        }
    }
    
    updatePuzzleDisplay(ui->widget_initialGrid, m_initialState);
    updatePuzzleDisplay(ui->widget_goalGrid, m_goalState);
    updatePuzzleDisplay(ui->widget_currentState, m_initialState);
    m_currentState = m_initialState;
    
    ui->statusbar->showMessage("已生成随机初始状态和目标状态");
}

void MainWindow::onManualState()
{
    // 直接使用字符串输入方式
    showStringInputDialog();
}



void MainWindow::onGridButtonClicked()
{
    QPushButton* button = qobject_cast<QPushButton*>(sender());
    if (!button) return;
    
    // 获取按钮的位置信息
    int row = button->property("row").toInt();
    int col = button->property("col").toInt();
    QString grid = button->property("grid").toString();
    
    // 只允许在手动输入模式下编辑初始和目标状态
    if (!m_isManualInput || grid == "current") return;
    
    // 弹出输入对话框
    bool ok;
    int maxValue = m_puzzleSize * m_puzzleSize - 1;
    QString prompt = QString("请输入数字 (0-%1，0表示空格):").arg(maxValue);
    int value = QInputDialog::getInt(this, "输入数字", prompt, 
                                   button->text() == " " ? 0 : button->text().toInt(), 
                                   0, maxValue, 1, &ok);
    
    if (ok) {
        // 检查输入的数字是否已经存在于当前网格中
        PuzzleState* targetState = nullptr;
        if (grid == "initial") {
            targetState = &m_initialState;
        } else if (grid == "goal") {
            targetState = &m_goalState;
        }
        
        if (targetState) {
            // 检查是否有重复数字（除了当前位置）
            bool duplicate = false;
            for (int i = 0; i < m_puzzleSize && !duplicate; i++) {
                for (int j = 0; j < m_puzzleSize && !duplicate; j++) {
                    if (i != row || j != col) {
                        if (targetState->getValue(i, j) == value) {
                            duplicate = true;
                        }
                    }
                }
            }
            
            if (duplicate) {
                QMessageBox::warning(this, "输入错误", 
                    QString("数字 %1 已经存在于当前网格中！").arg(value));
                return;
            }
            
            // 更新状态
            targetState->setValue(row, col, value);
            
            // 更新显示
            if (grid == "initial") {
                updatePuzzleDisplay(ui->widget_initialGrid, m_initialState);
            } else if (grid == "goal") {
                updatePuzzleDisplay(ui->widget_goalGrid, m_goalState);
            }
            

        }
    }
}

















void MainWindow::onClearResults()
{
    ui->tableWidget_results->setRowCount(0);
    ui->statusbar->showMessage("已清空结果");
}


void MainWindow::addResultToTable(const QString& algorithm, const SearchResult& result)
{
    int row = ui->tableWidget_results->rowCount();
    ui->tableWidget_results->insertRow(row);
    
    // 算法名称
    QTableWidgetItem* algorithmItem = new QTableWidgetItem(algorithm);
    algorithmItem->setTextAlignment(Qt::AlignCenter);
    ui->tableWidget_results->setItem(row, 0, algorithmItem);
    
    // 是否成功
    QTableWidgetItem* successItem = new QTableWidgetItem(result.success ? "是" : "否");
    successItem->setTextAlignment(Qt::AlignCenter);
    ui->tableWidget_results->setItem(row, 1, successItem);
    
    // 步数
    QTableWidgetItem* stepsItem = new QTableWidgetItem(QString::number(result.steps));
    stepsItem->setTextAlignment(Qt::AlignCenter);
    ui->tableWidget_results->setItem(row, 2, stepsItem);
    
    // 生成节点数
    QTableWidgetItem* generatedItem = new QTableWidgetItem(QString::number(result.nodesGenerated));
    generatedItem->setTextAlignment(Qt::AlignCenter);
    ui->tableWidget_results->setItem(row, 3, generatedItem);
    
    // 扩展节点数
    QTableWidgetItem* expandedItem = new QTableWidgetItem(QString::number(result.nodesExpanded));
    expandedItem->setTextAlignment(Qt::AlignCenter);
    ui->tableWidget_results->setItem(row, 4, expandedItem);
    
    // 运行时间（格式化为毫秒）
    QTableWidgetItem* timeItem = new QTableWidgetItem(QString::number(result.timeElapsed, 'f', 2) + " ms");
    timeItem->setTextAlignment(Qt::AlignCenter);
    ui->tableWidget_results->setItem(row, 5, timeItem);
}

void MainWindow::enableControls(bool enabled)
{
    ui->pushButton_runAll->setEnabled(enabled);
    
    ui->comboBox_size->setEnabled(enabled);
    ui->pushButton_default->setEnabled(enabled);
    ui->pushButton_random->setEnabled(enabled);
    ui->pushButton_manual->setEnabled(enabled);
}



bool MainWindow::checkSolvability()
{
    return m_initialState.isSolvable(m_goalState);
}





SearchAlgorithm* MainWindow::createAlgorithmById(int algorithmId)
{
    switch (algorithmId) {
        case 0: // A* Manhattan
            return new AStarAlgorithm(HeuristicType::MANHATTAN_DISTANCE);
        case 1: // A* Misplaced
            return new AStarAlgorithm(HeuristicType::MISPLACED_TILES);
        case 2: // BFS
            return new BFSAlgorithm();
        case 3: // DFS
            return new DFSAlgorithm(50);  // 增加深度限制到50，提高搜索成功率
        default:
            return nullptr;
    }
}

QString MainWindow::getAlgorithmNameById(int algorithmId)
{
    switch (algorithmId) {
        case 0: return "A*(曼哈顿距离)";
        case 1: return "A*(不在位数码数)";
        case 2: return "BFS";
        case 3: return "IDA*(深度优先+启发式指导)";
        default: return "未知";
    }
}

void MainWindow::onRunAllAlgorithms()
{
    if (m_isSearching) return;
    
    if (!checkSolvability()) {
        int initialInversions = m_initialState.getInversionsCount();
        int goalInversions = m_goalState.getInversionsCount();
        
        QMessageBox::warning(this, "无解", 
            QString("当前初始状态无法到达目标状态！\n\n"
                   "逆序数分析：\n"
                   "初始状态逆序数：%1\n"
                   "目标状态逆序数：%2\n\n"
                   "说明：对于3×3数码问题，初始状态和目标状态的逆序数必须具有相同的奇偶性才可解。")
                   .arg(initialInversions).arg(goalInversions));
        return;
    }
    
    m_isSearching = true;
    enableControls(false);
    ui->statusbar->showMessage("正在运行所有算法...");
    
    // 运行所有四种算法
    for (int i = 0; i < 4; ++i) {
        m_algorithm.reset(createAlgorithmById(i));
        if (m_algorithm) {
            SearchResult result = m_algorithm->search(m_initialState, m_goalState);
            addResultToTable(getAlgorithmNameById(i), result);
        }
    }
    
    m_isSearching = false;
    enableControls(true);
    ui->statusbar->showMessage("所有算法运行完成！");
}

void MainWindow::showStringInputDialog()
{
    // 创建自定义对话框
    QDialog dialog(this);
    dialog.setWindowTitle("手动设置状态");
    dialog.setModal(true);
    dialog.resize(300, 150);
    
    QVBoxLayout *layout = new QVBoxLayout(&dialog);
    
    // 添加说明标签
    QLabel *label = new QLabel("请选择要修改的状态:", &dialog);
    layout->addWidget(label);
    
    // 添加复选框
    QCheckBox *checkInitial = new QCheckBox("修改初始状态", &dialog);
    QCheckBox *checkTarget = new QCheckBox("修改目标状态", &dialog);
    checkInitial->setChecked(true); // 默认选中初始状态
    
    layout->addWidget(checkInitial);
    layout->addWidget(checkTarget);
    
    // 添加按钮
    QHBoxLayout *buttonLayout = new QHBoxLayout();
    QPushButton *okButton = new QPushButton("确定", &dialog);
    QPushButton *cancelButton = new QPushButton("取消", &dialog);
    
    buttonLayout->addWidget(okButton);
    buttonLayout->addWidget(cancelButton);
    layout->addLayout(buttonLayout);
    
    // 连接信号
    connect(okButton, &QPushButton::clicked, &dialog, &QDialog::accept);
    connect(cancelButton, &QPushButton::clicked, &dialog, &QDialog::reject);
    
    // 显示对话框
    if (dialog.exec() != QDialog::Accepted) {
        return; // 用户取消
    }
    
    bool modifyInitial = checkInitial->isChecked();
    bool modifyTarget = checkTarget->isChecked();
    
    // 检查是否至少选择了一个
    if (!modifyInitial && !modifyTarget) {
        QMessageBox::information(this, "提示", "请至少选择一个状态进行修改");
        return;
    }
    
    PuzzleState newInitialState = m_initialState; // 默认保持当前状态
    PuzzleState newTargetState = m_goalState;   // 默认保持当前状态
    
    // 输入初始状态（如果需要）
    if (modifyInitial) {
        bool ok;
        QString initialInput = QInputDialog::getText(this, "手动设置初始状态", 
            QString("请输入初始状态的数字序列（%1数码）:\n\n"
                    "格式说明：\n"
                    "- 输入%2个数字，用0表示空格\n"
                    "- 例如：123804765 表示:\n"
                    "  1 2 3\n"
                    "  8   4\n"
                    "  7 6 5")
                    .arg(m_puzzleSize * m_puzzleSize - 1)
                    .arg(m_puzzleSize * m_puzzleSize), 
            QLineEdit::Normal, "", &ok);
        
        if (!ok || initialInput.isEmpty()) {
            ui->statusbar->showMessage("手动设置已取消");
            return;
        }
        
        // 验证并解析初始状态
        if (!validatePuzzleString(initialInput)) {
            QMessageBox::warning(this, "输入错误", "初始状态格式不正确！\n请确保输入正确数量的数字，且每个数字都不重复。");
            return;
        }
        
        newInitialState = PuzzleState(m_puzzleSize);
        if (!parseStringToPuzzleState(initialInput, newInitialState)) {
            QMessageBox::warning(this, "解析错误", "无法解析初始状态！");
            return;
        }
    }
    
    // 输入目标状态（如果需要）
    if (modifyTarget) {
        bool ok;
        QString goalInput = QInputDialog::getText(this, "手动设置目标状态", 
            QString("请输入目标状态的数字序列（%1数码）:\n\n"
                    "格式说明：\n"
                    "- 输入%2个数字，用0表示空格\n"
                    "- 例如：123456780 表示:\n"
                    "  1 2 3\n"
                    "  4 5 6\n"
                    "  7 8  ")
                    .arg(m_puzzleSize * m_puzzleSize - 1)
                    .arg(m_puzzleSize * m_puzzleSize), 
            QLineEdit::Normal, "", &ok);
        
        if (!ok || goalInput.isEmpty()) {
            ui->statusbar->showMessage("手动设置已取消");
            return;
        }
        
        // 验证并解析目标状态
        if (!validatePuzzleString(goalInput)) {
            QMessageBox::warning(this, "输入错误", "目标状态格式不正确！\n请确保输入正确数量的数字，且每个数字都不重复。");
            return;
        }
        
        newTargetState = PuzzleState(m_puzzleSize);
        if (!parseStringToPuzzleState(goalInput, newTargetState)) {
            QMessageBox::warning(this, "解析错误", "无法解析目标状态！");
            return;
        }
    }
    
    // 验证可解性
    if (!newInitialState.isSolvable(newTargetState)) {
        int initialInversions = newInitialState.getInversionsCount();
        int goalInversions = newTargetState.getInversionsCount();
        
        QMessageBox::warning(this, "无解问题", 
            QString("从设置的初始状态无法到达目标状态！\n\n"
                   "逆序数分析：\n"
                   "初始状态逆序数：%1 (%2)\n"
                   "目标状态逆序数：%3 (%4)\n\n"
                   "可解条件：对于3×3数码问题，初始状态和目标状态的逆序数必须具有相同的奇偶性。\n"
                   "当前状态：%5\n\n"
                   "请重新设置状态。")
                   .arg(initialInversions)
                   .arg(initialInversions % 2 == 0 ? "偶数" : "奇数")
                   .arg(goalInversions)
                   .arg(goalInversions % 2 == 0 ? "偶数" : "奇数")
                   .arg(initialInversions % 2 == goalInversions % 2 ? "奇偶性相同但仍无解" : "奇偶性不同，无解"));
        return;
    }
    
    // 更新状态
    m_initialState = newInitialState;
    m_goalState = newTargetState;
    m_currentState = m_initialState;
    
    // 更新显示
    updatePuzzleDisplay(ui->widget_initialGrid, m_initialState);
    updatePuzzleDisplay(ui->widget_goalGrid, m_goalState);
    updatePuzzleDisplay(ui->widget_currentState, m_currentState);
    
    // 生成状态描述
    QString stateDescription;
    if (modifyInitial && modifyTarget) {
        stateDescription = "同时修改了初始状态和目标状态";
    } else if (modifyInitial) {
        stateDescription = "修改了初始状态";
    } else {
        stateDescription = "修改了目标状态";
    }
    
    ui->statusbar->showMessage(QString("手动设置完成：%1").arg(stateDescription));
}

bool MainWindow::validatePuzzleString(const QString& input)
{
    int expectedLength = m_puzzleSize * m_puzzleSize;
    
    // 检查长度
    if (input.length() != expectedLength) {
        return false;
    }
    
    // 检查字符是否都是有效的数字/字母
    QSet<QChar> usedChars;
    QSet<int> validValues;
    
    // 生成有效值集合
    for (int i = 0; i < expectedLength; i++) {
        validValues.insert(i);
    }
    
    for (int i = 0; i < input.length(); i++) {
        QChar ch = input[i].toUpper();
        int value = -1;
        
        // 转换字符到数值
        if (ch.isDigit()) {
            value = ch.digitValue();
        } else if (ch >= 'A' && ch <= 'F') {
            value = ch.unicode() - 'A' + 10;
        } else {
            return false; // 无效字符
        }
        
        // 检查值是否在有效范围内
        if (!validValues.contains(value)) {
            return false;
        }
        
        // 检查是否重复
        if (usedChars.contains(ch)) {
            return false;
        }
        
        usedChars.insert(ch);
    }
    
    return usedChars.size() == expectedLength;
}

bool MainWindow::parseStringToPuzzleState(const QString& input, PuzzleState& state)
{
    if (!validatePuzzleString(input)) {
        return false;
    }
    
    int index = 0;
    for (int row = 0; row < m_puzzleSize; row++) {
        for (int col = 0; col < m_puzzleSize; col++) {
            QChar ch = input[index].toUpper();
            int value = -1;
            
            // 转换字符到数值
            if (ch.isDigit()) {
                value = ch.digitValue();
            } else if (ch >= 'A' && ch <= 'F') {
                value = ch.unicode() - 'A' + 10;
            } else {
                return false;
            }
            
            state.setValue(row, col, value);
            index++;
        }
    }
    
    return true;
}



void MainWindow::startAlgorithmDemo(SearchAlgorithm* algorithm, const QString& algorithmName)
{
    // 如果正在演示，先停止
    if (m_isDemoRunning) {
        m_demoTimer->stop();
        m_isDemoRunning = false;
    }
    
    // 清空日志并重置计数器
    clearDemoLog();
    
    // 自动重置当前状态为初始状态
    m_currentState = m_initialState;
    updatePuzzleDisplay(ui->widget_currentState, m_currentState);
    ui->statusbar->showMessage(QString("准备使用 %1 算法演示...").arg(algorithmName));
    
    // 添加演示开始日志
    addLogEntry(QString("开始 %1 算法演示").arg(algorithmName));
    addLogEntry("");
    
    // 检查初始状态是否已经是目标状态
    if (m_initialState == m_goalState) {
        QMessageBox::information(this, "提示", "初始状态已经是目标状态！");
        delete algorithm;
        return;
    }
    
    // 检查可解性
    if (!checkSolvability()) {
        addLogEntry("错误: 初始状态无法到达目标状态！");
        QMessageBox::warning(this, "错误", "初始状态无法到达目标状态！");
        delete algorithm;
        return;
    }
    
    // 使用指定算法求解路径
    std::unique_ptr<SearchAlgorithm> algorithmPtr(algorithm);
    SearchResult result = algorithmPtr->search(m_initialState, m_goalState);
    
    if (!result.success) {
        addLogEntry(QString("错误: %1 算法无法找到解决方案！").arg(algorithmName));
        QMessageBox::warning(this, "错误", QString("使用 %1 算法无法找到解决方案！").arg(algorithmName));
        return;
    }
    
    // 保存解决路径用于演示（不添加到结果表格）
    m_solutionPath = result.path;
    m_currentAlgorithmName = algorithmName;
    m_currentDemoStep = 0;
    m_isDemoRunning = true;
    
    // 显示演示开始信息
    ui->statusbar->showMessage(QString("开始 %1 算法演示，共 %2 步...")
                              .arg(algorithmName)
                              .arg(m_solutionPath.size() - 1));
    
    // 启动演示计时器，每1秒演示一步
    m_demoTimer->start(1000);
    
    // 更新演示控制按钮状态
    updateDemoControlButtons();
}



void MainWindow::onDemoAStarManhattan()
{
    startAlgorithmDemo(new AStarAlgorithm(HeuristicType::MANHATTAN_DISTANCE), "A* (曼哈顿距离)");
}

void MainWindow::onDemoAStarMisplaced()
{
    startAlgorithmDemo(new AStarAlgorithm(HeuristicType::MISPLACED_TILES), "A* (不在位数码数)");
}

void MainWindow::onDemoBFS()
{
    startAlgorithmDemo(new BFSAlgorithm(), "宽度优先搜索 (BFS)");
}

void MainWindow::onDemoDFS()
{
    startAlgorithmDemo(new DFSAlgorithm(50), "IDA* (深度优先+启发式指导)");
}

void MainWindow::onDemoStep()
{
    if (!m_isDemoRunning || m_solutionPath.empty()) {
        return;
    }
    
    // 检查是否已经演示完成
    if (m_currentDemoStep >= static_cast<int>(m_solutionPath.size())) {
        // 演示完成
        m_demoTimer->stop();
        m_isDemoRunning = false;
        
        addLogEntry("");
        addLogEntry(QString("%1 算法演示完成！").arg(m_currentAlgorithmName));
        
        ui->statusbar->showMessage(QString("%1 算法演示完成！")
                                  .arg(m_currentAlgorithmName));
        
        QMessageBox::information(this, "演示完成", 
            QString("%1 算法演示完成！\n总共演示了 %2 步")
            .arg(m_currentAlgorithmName)
            .arg(m_solutionPath.size() - 1));
        
        // 更新演示控制按钮状态
        updateDemoControlButtons();
        return;
    }
    
    // 更新当前状态为路径中的下一步
    m_currentState = m_solutionPath[m_currentDemoStep];
    updatePuzzleDisplay(ui->widget_currentState, m_currentState);
    
    // 添加步骤日志
    if (m_currentDemoStep == 0) {
        addLogEntry("初始状态:");
    } else {
        addLogEntry(QString("第%1步:").arg(m_currentDemoStep));
    }
    addLogEntry("");
    addLogEntry(formatPuzzleState(m_currentState));
    addLogEntry("");
    
    // 更新状态栏信息
    if (m_currentDemoStep == 0) {
        ui->statusbar->showMessage(QString("%1 算法演示中... 初始状态")
                                  .arg(m_currentAlgorithmName));
    } else {
        ui->statusbar->showMessage(QString("%1 算法演示中... 第 %2/%3 步")
                                  .arg(m_currentAlgorithmName)
                                  .arg(m_currentDemoStep)
                                  .arg(m_solutionPath.size() - 1));
    }
    
    // 移动到下一步
    m_currentDemoStep++;
}

void MainWindow::onDemoPause()
{
    if (m_isDemoRunning && m_demoTimer->isActive()) {
        m_demoTimer->stop();
        ui->statusbar->showMessage(QString("%1 算法演示已暂停")
                                  .arg(m_currentAlgorithmName));
        updateDemoControlButtons();
    }
}

void MainWindow::onDemoResume()
{
    if (m_isDemoRunning && !m_demoTimer->isActive()) {
        m_demoTimer->start(1000);
        ui->statusbar->showMessage(QString("%1 算法演示继续中...")
                                  .arg(m_currentAlgorithmName));
        updateDemoControlButtons();
    }
}

void MainWindow::onDemoStop()
{
    if (m_isDemoRunning) {
        m_demoTimer->stop();
        m_isDemoRunning = false;
        m_solutionPath.clear();
        m_currentDemoStep = 0;
        
        ui->statusbar->showMessage(QString("%1 算法演示已停止")
                                  .arg(m_currentAlgorithmName));
        updateDemoControlButtons();
    }
}

void MainWindow::updateDemoControlButtons()
{
    bool isRunning = m_isDemoRunning;
    bool isPaused = isRunning && !m_demoTimer->isActive();
    bool isActive = isRunning && m_demoTimer->isActive();
    
    ui->pushButton_demo_pause->setEnabled(isActive);
    ui->pushButton_demo_resume->setEnabled(isPaused);
    ui->pushButton_demo_stop->setEnabled(isRunning);
}

void MainWindow::addLogEntry(const QString& message)
{
    ui->textEdit_demoLog->append(message);
    
    // 自动滚动到底部
    QTextCursor cursor = ui->textEdit_demoLog->textCursor();
    cursor.movePosition(QTextCursor::End);
    ui->textEdit_demoLog->setTextCursor(cursor);
}

void MainWindow::onClearLog()
{
    ui->textEdit_demoLog->clear();
    m_logStepCounter = 0;
    addLogEntry("日志已清空");
}

void MainWindow::clearDemoLog()
{
    ui->textEdit_demoLog->clear();
    m_logStepCounter = 0;
}

QString MainWindow::formatPuzzleState(const PuzzleState& state)
{
    QString result;
    int size = state.getSize();
    
    for (int row = 0; row < size; ++row) {
        result += " ";  // 每行前面加一个空格缩进
        for (int col = 0; col < size; ++col) {
            int value = state.getValue(row, col);
            if (value == 0) {
                result += "  ";  // 空格用两个空格表示
            } else {
                result += QString("%1").arg(value, 2);  // 数字右对齐，占2个字符宽度
            }
            if (col < size - 1) {
                result += " ";  // 列之间加一个空格分隔
            }
        }
        if (row < size - 1) {
            result += "\n";  // 除了最后一行，每行后面加换行
        }
    }
    
    return result;
}
